package com.speedata.uhf;

import android.app.AlertDialog;
import android.app.Instrumentation;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import androidx.core.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.WindowManager;

import com.speedata.libuhf.IUHFService;
import com.speedata.libuhf.UHFManager;
import com.speedata.libuhf.bean.SpdInventoryData;
import com.speedata.libuhf.interfaces.OnSpdBanMsgListener;
import com.speedata.libuhf.interfaces.OnSpdInventoryListener;
import com.speedata.libuhf.utils.DataConversionUtils;
import com.speedata.libuhf.utils.SharedXmlUtil;
import com.speedata.uhf.adapter.UhfInfoBean;
import com.speedata.uhf.floatball.FloatBallManager;
import com.speedata.uhf.floatball.FloatWarnManager;
import com.speedata.uhf.floatball.ModeManager;
import com.speedata.uhf.httpserver.ArtemisHttpServer;
import com.speedata.uhf.libutils.PlaySoundPool;
import com.yhao.floatwindow.FloatWindow;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 接受广播  触发盘点，返回EPC
 * Receive broadcasting
 * Trigger inventory
 * Returns the EPC
 *
 * @author My_PC
 */
public class MyService extends Service {

    /**
     * 按设备侧键触发的扫描广播
     * Scan broadcast triggered by pressing device side key
     */
    public static final String START_SCAN = "com.spd.action.start_uhf";
    public static final String STOP_SCAN = "com.spd.action.stop_uhf";
    // 写卡
    public static final String WRITE_CARD = "com.spd.uhf_write";
    // 设置功率
    public static final String SET_POWER = "com.spd.uhf_set_power";
    public static final String CUSTOM_SCAN = "com.spd.action.KEY_UHF";



    public static final String ACTION_SEND_EPC = "com.se4500.onDecodeComplete";
    public static final String ACTION_SEND_DATA = "com.spd.action.data";
    public static final String UPDATE = "uhf.update";
    private static final String TAG = "UHFService";
    /**
     * 超高频单次模式
     * UHF single mode
     */
    public final int MODE_UHF = 2;
    /**
     * 超高频重复模式
     * UHF more mode
     */
    public final int MODE_UHF_RE = 3;
    PlaySoundPool playSoundPool;

    private boolean isStart = false;
    private UhfBinder mBinder = new UhfBinder();
    private volatile boolean isLoop = false;
    private long startTime = 0;
    private List<String> linkedList;
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "===rece===action===" + action);
            //            assert action != null;
            if (Objects.equals(action, Intent.ACTION_SCREEN_OFF)) {
                Log.d(TAG, "===熄屏了===" + action);
                IUHFService iuhfService = MyApp.getInstance().getIuhfService();
                if (iuhfService != null) {
                    iuhfService.inventoryStop();
                    MyApp.getInstance().getIuhfService().switchInvMode(0);
                    iuhfService.closeDev();
                    MyApp.isOpenDev = false;
                    Log.d(TAG, "===熄屏下电了===" + action);
                }
            }
            if (Objects.equals(action, Intent.ACTION_SCREEN_ON)) {
                initUHF();
                if (openDev()) {
                    Log.d(TAG, "===亮屏了==上电成功===" + action);
                    if (!MyApp.isFastMode) {
                        MyApp.getInstance().initParam();
                    } else {
                        MyApp.getInstance().getIuhfService().switchInvMode(1);
                    }

                }
            }

            if (MyApp.isOpenServer) {
                switch (Objects.requireNonNull(action)) {
                    case START_SCAN:
                        //启动超高频扫描   start
                        if (openDev()) {
                            getExtraStartParameterAndSet(intent);
                            startScan();
                        }
                        break;
                    case STOP_SCAN:
                        if (MyApp.isLongDown) {
                            //停止盘点      stop
                            cancelTimer();
                            return;
                        }
                        break;
                    case UPDATE:
                        initUHF();
                        break;
                    case WRITE_CARD:
                        //TODO write
                        byte[] epc = intent.getByteArrayExtra("epc");
                        byte[] writeData = intent.getByteArrayExtra("writeData");
                        int mode = intent.getIntExtra("mode", 0);
                        int block = intent.getIntExtra("block", 0);
                        String password = intent.getStringExtra("password");

                        MyApp.getInstance().getIuhfService().selectCard(mode, epc, true);
                        MyApp.getInstance().getIuhfService().writeArea(mode, 0, block, password, writeData);
                        break;
                    case SET_POWER:
                        int power = intent.getIntExtra("power", 30);
                        MyApp.getInstance().getIuhfService().setAntennaPower(power);
                        break;
                    case CUSTOM_SCAN:
                        final int action2 = intent.getIntExtra("keyAction", KeyEvent.ACTION_DOWN);
                        if (action2 == KeyEvent.ACTION_DOWN) {
                            if (openDev()) {
                                startScan();
                            }
                        } else if (action2 == KeyEvent.ACTION_UP) {
                            if (MyApp.isLongDown) {
                                //停止盘点      stop
                                cancelTimer();
                                return;
                            }
                        }
                        break;

                    default:
                        break;
                }
            }
        }
    };

    private void getExtraStartParameterAndSet(Intent intent) {
        boolean isExtraData = intent.getBooleanExtra("extradata", false);
        if (isExtraData) {
            int userLen = intent.getIntExtra("userLen", 0);
            int userStart = intent.getIntExtra("userStart", 0);
            int dataType = intent.getIntExtra("dataType", 0);
//            int currentMode = intent.getIntExtra("current_mode", 2);
//            SharedXmlUtil.getInstance(this).write("current_mode", currentMode);
            Log.d(TAG, "extradata==userLen=" + userLen + " userStart=" + userStart + " mode=" + dataType);
            int result = 0;
            if (dataType == 2) {
                result = MyApp.getInstance().getIuhfService().setInvMode(2, userStart, userLen);
            } else {
//                Log.d(TAG, "");
                result = MyApp.getInstance().getIuhfService().setInvMode(dataType, 0, 12);
            }
            Log.d(TAG, "setInvMode result=" + result);
        }

    }

    public MyService() {
    }

    public static void simulateKey(final int KeyCode) {
        new Thread() {
            @Override
            public void run() {
                try {
                    sleep(100);
                    Instrumentation inst = new Instrumentation();
                    inst.sendKeyDownUpSync(KeyCode);
                    Log.d(TAG, "===SendStopFlag===" + KeyCode);
                } catch (Exception e) {
                    Log.e(TAG, "sendKeyDownUpSync:" + e.toString());
                }
            }
        }.start();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "===onCreate===");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("UHFService", "UHFService", NotificationManager.IMPORTANCE_LOW);
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            if (manager == null) {
                return;
            }
            manager.createNotificationChannel(channel);
            //此处的channelId必须和上面NotificationChannel设置的id一致
            Notification notification = new NotificationCompat.Builder(this, "UHFService")
                    .setAutoCancel(true)
                    .setCategory(Notification.CATEGORY_SERVICE)
                    .setOngoing(true)
                    .setPriority(NotificationManager.IMPORTANCE_LOW)
                    .setSmallIcon(R.mipmap.icon_uhf)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.icon_uhf))
                    .build();
            //注意 id不能为0
            startForeground(107, notification);
        }
        //        setBuilder();
        initReceive();
        initUHF();
        //开启网络监听request请求
        ArtemisHttpServer.getInstance().start();
    }

    private void createTimer() {
        if (MyApp.isStopTime) {
            isLoop = true;
            startTime = System.currentTimeMillis();
            StopTimeThread stopTimeThread = new StopTimeThread();
            stopTimeThread.start();
        }
    }

    private void cancelTimer() {
        if (MyApp.getInstance().getIuhfService() != null) {
            MyApp.getInstance().getIuhfService().inventoryStop();
        }
        MyApp.isStart = false;
        sendStopFlag();
        isLoop = false;

    }

    private void initUHF() {
        playSoundPool = PlaySoundPool.getPlaySoundPool(getApplicationContext());
        Log.e(TAG, "initUHF");
        if (MyApp.getInstance().getIuhfService() != null) {
            openDev();
        } else {
            MyApp.getInstance().setIuhfService();
            openDev();
        }
    }

    /**
     * 注册广播
     */
    private void initReceive() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(START_SCAN);
        filter.addAction(STOP_SCAN);
        filter.addAction(UPDATE);
        filter.addAction(CUSTOM_SCAN);

        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        registerReceiver(receiver, filter);
    }

    private void startScan() {
        if (MyApp.getInstance().getIuhfService() != null) {
            int modeLeft = SharedXmlUtil.getInstance(this).read("current_mode_left", 6);
            int modeRight = SharedXmlUtil.getInstance(this).read("current_mode_right", 6);
            int mode = ModeManager.getInstance(MyService.this).getScanMode();
            boolean isOnce = false;
            if (mode == MODE_UHF || modeLeft == MODE_UHF || modeRight == MODE_UHF) {
                isOnce = true;
            }
            boolean finalIsOnce = isOnce;
            MyApp.getInstance().getIuhfService().setOnInventoryListener(new OnSpdInventoryListener() {
                @Override
                public void getInventoryData(SpdInventoryData var1) {
                    String epc = var1.getEpc();
                    if (SharedXmlUtil.getInstance(MyService.this).read(MyApp.EPC_OR_TID, false)) {
                        epc = var1.getTid();
                    }
                    if (!TextUtils.isEmpty(epc) && MyApp.isStart && !linkedList.contains(epc)) {
                        if (MyApp.isFilter) {
                            linkedList.add(epc);
                        }
                        if (SharedXmlUtil.getInstance(MyService.this).read("server_sound", true)) {
                            playSoundPool.playLaser();
//                            soundPool.play(soundId, 1, 1, 0, 0, 1);
                        }
                        if (SharedXmlUtil.getInstance(MyService.this).read(MyApp.IS_FOCUS_SHOW, true)) {
                            if (SharedXmlUtil.getInstance(MyService.this).read(MyApp.SERVER_IS_ASCII, false)) {
                                byte[] tid = DataConversionUtils.HexString2Bytes(epc);
                                epc = new String(tid, StandardCharsets.UTF_8);
                            }
                            sendEpc(epc);
                        }
                        sendData(var1);
                        if (finalIsOnce) {
                            //停止盘点 stop
                            Log.e(TAG, "finalIsOnce = true");
                            MyApp.getInstance().getIuhfService().inventoryStop();
                            MyApp.isStart = false;
                            sendStopFlag();
                            if (linkedList != null) {
                                linkedList.clear();
                                linkedList = null;
                            }
                        }
                    }
                }

                @Override
                public void onInventoryStatus(int status) {

                }
            });
            if (!MyApp.isStart) {
                MyApp.getInstance().getIuhfService().inventoryStart();
                linkedList = new ArrayList<>();
                MyApp.isStart = true;
                createTimer();
            } else {
                cancelTimer();
                if (linkedList != null) {
                    linkedList.clear();
                    linkedList = null;
                }
            }
        }
    }

    private void sendData(SpdInventoryData var1) {
        if (MyApp.list != null) {
            if (MyApp.list.size() > 5000) {
                MyApp.list.clear();
            }
            MyApp.list.add(new UhfInfoBean(var1.getEpc(), var1.getTid(), var1.getRssi()));
        }

        Intent intent = new Intent();
        intent.setAction(ACTION_SEND_DATA);
        Bundle bundle = new Bundle();
        bundle.putString("epc", var1.getEpc());
        bundle.putString("tid", var1.getTid());
        bundle.putString("rssi", var1.getRssi());
        intent.putExtras(bundle);
        sendBroadcast(intent);

        SharedXmlUtil sharedXmlUtil = SharedXmlUtil.getInstance(MyService.this);
        String action = sharedXmlUtil.read(MyApp.ACTION_SEND_CUSTOM, "");
        String keyEpc = sharedXmlUtil.read(MyApp.ACTION_KEY_EPC, "");
        String keyTid = sharedXmlUtil.read(MyApp.ACTION_KEY_TID, "");
        String keyRssi = sharedXmlUtil.read(MyApp.ACTION_KEY_RSSI, "");
        if (!action.isEmpty()) {
            Intent intentCustom = new Intent(action);
            Bundle bundle1 = new Bundle();
            if (!keyEpc.isEmpty()) {
                bundle1.putString(keyEpc, var1.getEpc());
            }
            if (!keyTid.isEmpty()) {
                bundle1.putString(keyTid, var1.getTid());
            }
            if (!keyRssi.isEmpty()) {
                bundle1.putString(keyRssi, var1.getRssi());
            }
            intentCustom.putExtras(bundle1);
            sendBroadcast(intentCustom);
        }
        Log.d(TAG, "===sendData===" + action);
    }

    private void sendEpc(String epc) {
        String prefix;
        String suffix;
        switch (MyApp.mPrefix) {
            case 0:
                prefix = "\n";
                break;
            case 1:
                prefix = " ";
                break;
            case 2:
                prefix = "\r\n";
                break;
            case 3:
                prefix = "";
                break;
            default:
                prefix = SharedXmlUtil.getInstance(MyService.this).read(MyApp.SERVER_PREFIX_CUSTOM, "");
                break;
        }
        switch (MyApp.mSuffix) {
            case 0:
                suffix = "\n";
                break;
            case 1:
                suffix = " ";
                break;
            case 2:
                suffix = "\r\n";
                break;
            case 3:
                suffix = "";
                break;
            default:
                suffix = SharedXmlUtil.getInstance(MyService.this).read(MyApp.SERVER_SUFFIX_CUSTOM, ",");
                break;
        }
        epc = prefix + epc + suffix;
        Intent intent = new Intent();
        intent.setAction(ACTION_SEND_EPC);
        Bundle bundle = new Bundle();
        bundle.putString("se4500", epc);
        intent.putExtras(bundle);
        sendBroadcast(intent);
        Log.d(TAG, "===SendEpc===" + epc);
    }

    private void sendStopFlag() {
        String stopFlag = "";
        switch (MyApp.mStopFlag) {
            case 0:
                stopFlag = "\n";
                break;
            case 1:
                stopFlag = " ";
                break;
            case 2:
                stopFlag = "\r\n";
                break;
            case 3:
                break;
            case 4:
                simulateKey(KeyEvent.KEYCODE_ENTER);
                break;
            default:
                stopFlag = SharedXmlUtil.getInstance(MyService.this).read(MyApp.SERVER_STOP_FLAG_CUSTOM, "");
                break;
        }
        if (stopFlag.isEmpty()) {
            return;
        }
        Intent intent = new Intent();
        intent.setAction(ACTION_SEND_EPC);
        Bundle bundle = new Bundle();
        bundle.putString("se4500", stopFlag);
        intent.putExtras(bundle);
        sendBroadcast(intent);
        Log.d(TAG, "===SendStopFlag===" + stopFlag);
    }

    /**
     * 上电开串口
     * Power on and open serial port
     */
    private boolean openDev() {
        Log.d("zzc", "==MyService==openDev==" + MyApp.isOpenDev);
        if (!MyApp.isOpenDev) {
            if (MyApp.getInstance().getIuhfService() != null) {
                final int i = MyApp.getInstance().getIuhfService().openDev();
                if (i != 0) {
                    AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(R.string.DIA_ALERT).setMessage(R.string.DEV_OPEN_ERR).setPositiveButton(R.string.DIA_CHECK, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Log.d(TAG, "===openDev===失败" + i);
                        }
                    }).create();
                    alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                    alertDialog.show();
                    MyApp.isOpenDev = false;
                    return false;
                } else {
                    Log.d(TAG, "===openDev===成功");
                    MyApp.isOpenDev = true;

                    if ("open".equals(SharedXmlUtil.getInstance(MyService.this).read("floatWindow", "close"))) {
                        FloatBallManager.getInstance(getApplicationContext());
                        if (FloatBallManager.getFloatBallManager() != null) {
                            FloatWindow.get("FloatBallTag").show();
                        }
                    }

                    return true;
                }
            }
            MyApp.isOpenDev = false;
            return false;
        } else {

            if ("open".equals(SharedXmlUtil.getInstance(MyService.this).read("floatWindow", "close"))) {
                FloatBallManager.getInstance(getApplicationContext());
                if (FloatBallManager.getFloatBallManager() != null) {
                    FloatWindow.get("FloatBallTag").show();
                }
            }

            return true;
        }
    }

    private void setBuilder() {
        UHFManager uhfManager = new UHFManager();
        uhfManager.setOnBanMsgListener(new OnSpdBanMsgListener() {
            @Override
            public void getBanMsg(String var1) {
                Log.e("zzc:UHFService", "====监听报警====");
                if (var1.contains("Low")) {
                    var1 = getResources().getString(R.string.low_power);
                } else if (var1.contains("High")) {
                    var1 = getResources().getString(R.string.high_temp);
                }
                FloatWarnManager.getInstance(getApplicationContext(), var1);
                FloatWarnManager floatWarnManager = FloatWarnManager.getFloatWarnManager();
                if (floatWarnManager != null) {
                    FloatWindow.get("FloatWarnTag").show();
                }
            }
        });

    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "===onDestroy===");
        ArtemisHttpServer.getInstance().stop();

        if (receiver != null) {
            unregisterReceiver(receiver);
        }
        super.onDestroy();
    }

    class UhfBinder extends Binder {

        void initUHF() {
            Log.d(TAG, "initUHF");
            initUHF();
        }

        public int releaseUHF() {
            Log.d("MyService", "getProgress executed");
            return 0;
        }

    }

    private class StopTimeThread extends Thread {
        @Override
        public void run() {
            if (MyApp.mStopTime == null || MyApp.mStopTime.isEmpty()) {
                MyApp.mStopTime = "0";
            }
            int stopTime = Integer.parseInt(MyApp.mStopTime);
            while (isLoop) {
                if ((System.currentTimeMillis() - startTime) >= (stopTime * 1000)) {
                    cancelTimer();
                }
                SystemClock.sleep(10);
            }
        }
    }
}
